package com.ev.hr.service.impl;

import com.ev.apis.model.DsResultResponse;
import com.ev.custom.domain.ContentAssocDO;
import com.ev.custom.service.ContentAssocService;
import com.ev.framework.config.ConstantForHr;
import com.ev.framework.il8n.MessageSourceHandler;
import com.ev.framework.utils.BeanUtils;
import com.ev.framework.utils.R;
import com.ev.framework.utils.StringUtils;
import com.ev.hr.dao.CandidateFollowDao;
import com.ev.hr.dao.CandidateInfoDao;
import com.ev.hr.dao.InterviewRecordDao;
import com.ev.hr.dao.InterviewRecordDetailDao;
import com.ev.hr.domain.CandidateInfoDO;
import com.ev.hr.domain.InterviewRecordDO;
import com.ev.hr.enums.InterviewStateDict;
import com.ev.hr.enums.ResumeStateDict;
import com.ev.hr.service.CandidateInfoService;
import com.ev.hr.vo.CandidateFollowPageParam;
import com.ev.hr.vo.CandidateInfoPageParam;
import com.ev.hr.vo.CandidateInfoVO;
import com.ev.system.domain.UserDO;
import com.ev.system.service.UserService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;


@Service
public class CandidateInfoServiceImpl implements CandidateInfoService {
	@Autowired
	private CandidateInfoDao candidateInfoDao;
	@Autowired
	private ContentAssocService contentAssocService;
	@Autowired
	private CandidateFollowDao candidateFollowDao;
	@Autowired
	private InterviewRecordDetailDao interviewRecordDetailDao;
	@Autowired
	private InterviewRecordDao interviewRecordDao;
	@Autowired
	private UserService userService;
	@Autowired
	private MessageSourceHandler messageSourceHandler;
	
	@Override
	public CandidateInfoDO get(Long id){
		return candidateInfoDao.get(id);
	}
	
	@Override
	public List<CandidateInfoDO> list(Map<String, Object> map){
		return candidateInfoDao.list(map);
	}
	
	@Override
	public int count(Map<String, Object> map){
		return candidateInfoDao.count(map);
	}
	
	@Override
	public int save(CandidateInfoDO candidateInfo){
		return candidateInfoDao.save(candidateInfo);
	}
	
	@Override
	public int update(CandidateInfoDO candidateInfo){
		return candidateInfoDao.update(candidateInfo);
	}

	@Override
	public int updateAll(CandidateInfoDO candidateInfo){
		return candidateInfoDao.updateAll(candidateInfo);
	}
	
	@Override
	public int remove(Long id){
		return candidateInfoDao.remove(id);
	}
	
	@Override
	public int batchRemove(Long[] ids){
		List<CandidateInfoDO> list = Lists.newArrayList();
		CandidateInfoDO candidateInfoDO ;
		for (Long id : ids) {
			candidateInfoDO = new CandidateInfoDO();
			candidateInfoDO.setId(id);
			candidateInfoDO.setDelFlag(1);
			list.add(candidateInfoDO);
		}
		return candidateInfoDao.batchUpdate(list);
	}

	@Override
	public R saveAndVerify(CandidateInfoVO saveParam){
		List<ContentAssocDO> contentAssocList = saveParam.getContentAssocList();

		CandidateInfoDO candidateInfoDO = new CandidateInfoDO();
		BeanUtils.copyProperties(saveParam,candidateInfoDO);
		String mobilePhone = saveParam.getMobilePhone();
		if (mobilePhone != null) {
			Map<String,Object> param = Maps.newHashMap();
			param.put("mobilePhone", mobilePhone);
			List<CandidateInfoDO> list = this.list(param);
			if(list.size()> 0){
				CandidateInfoDO oldCandidateInfo = list.get(0);
				if (Objects.equals(oldCandidateInfo.getResumeState(), ResumeStateDict.BLACKLIST.getId())) {
					// 当前应聘人在黑名单
					return R.error(messageSourceHandler.getMessage("hr.resume.inBlackList",null));
				}
				// 若简历库中已存在则更新简历
				candidateInfoDO.setId(oldCandidateInfo.getId());
				candidateInfoDO.setDelFlag(0);
			}
		}
		Long id = candidateInfoDO.getId();

		if(id==null){
			// 新增简历后修改简历状态为未面试
			candidateInfoDO.setInterviewState(InterviewStateDict.NOT_START.getId());
			candidateInfoDao.save(candidateInfoDO);
			id = candidateInfoDO.getId();
		}else {
			// 修改
			Long[] ids = {id};
			contentAssocService.removeByAssocIdAndType(ids, ConstantForHr.RESUME_FILE);
			candidateInfoDao.update(candidateInfoDO);
		}

		if (contentAssocList!=null&&contentAssocList.size()>0) {
			contentAssocService.saveListForEntity(id, contentAssocList, ConstantForHr.RESUME_FILE);
		}

		Map<String,Object> result = Maps.newHashMap();
		result.put("id",id);
		return R.ok(result);
	}

	@Override
	public Map<String, Object> getById(Long id) {
		Map<String, Object> candidateInfo = candidateInfoDao.getById(id);
		if (candidateInfo != null) {
			Map<String,Object> result = Maps.newHashMap();
			// 获取附件
			Map<String, Object> param = Maps.newHashMap();
			param.put("assocId", id);
			param.put("assocType", ConstantForHr.RESUME_FILE);
			List<ContentAssocDO> resumeFile = contentAssocService.list(param);
			candidateInfo.put("resumeFile", resumeFile);

			// 获取简历跟进记录
			CandidateFollowPageParam candidateFollowPageParam = new CandidateFollowPageParam();
			candidateFollowPageParam.setCandidateId(id);
			candidateFollowPageParam.setPagesize(Integer.MAX_VALUE);
			List<Map<String, Object>> followList = candidateFollowDao.pageList(candidateFollowPageParam);
			candidateInfo.put("followList",followList);

			//  获取面试记录
			param.clear();
			param.put("candidateId",id);
			List<InterviewRecordDO> recordDOS = interviewRecordDao.list(param);
			List<Long> idList = recordDOS
					.stream()
					.map(InterviewRecordDO::getId)
					.collect(Collectors.toList());
			if (idList.size() > 0) {
				param.clear();
				param.put("recordIdList", idList);
				param.put("sort","id");
				param.put("order","ASC");
				List<Map<String, Object>> recordDetailList = interviewRecordDetailDao.listForMap(param);

				param.clear();
				List<UserDO> employeeInfoList = userService.list(param);
				Map<Long, String> userMap = employeeInfoList
						.stream()
						.collect(Collectors.toMap(UserDO::getUserId, UserDO::getName));

				candidateInfo.put("interviewRecordList",recordDetailList);
				for (Map<String, Object> recordDetailMap : recordDetailList) {
					String interviewers = recordDetailMap.get("interviewer").toString();
					List<String> interviewer = Lists.newArrayList(interviewers.split(","));
					interviewer.removeIf(String::isEmpty);
					interviewer.replaceAll(e -> userMap.get(Long.parseLong(e)));
					interviewers = StringUtils.join(interviewer.toArray(), ",");
					recordDetailMap.put("interviewerName", interviewers);
				}
			}

			result.put("data",candidateInfo);
			return R.ok(result);
		}
		return R.error();
	}

	@Override
	public Map<String, Object> pageList(CandidateInfoPageParam pageParam) {
		Map<String, Object> result = Maps.newHashMap();
		pageParam.setAdvertisePositionName(StringUtils.sqlLike(pageParam.getAdvertisePositionName()));
		pageParam.setCandidateName(StringUtils.sqlLike(pageParam.getCandidateName()));
		if(pageParam.getResumeState()==null){
			pageParam.setInterviewState(InterviewStateDict.NOT_START.getId());
		}
		List<Map<String, Object>> data = candidateInfoDao.pageList(pageParam);
		if (data.size() > 0) {
			List<Object> idList = data
					.stream()
					.map(e -> e.get("id"))
					.collect(Collectors.toList());
			Map<String, Object> param = Maps.newHashMap();
			param.put("assocIds", idList);
			param.put("assocType", ConstantForHr.RESUME_FILE);
			List<ContentAssocDO> resumeFileList = contentAssocService.list(param);
			Map<Long, List<ContentAssocDO>> collect = resumeFileList
					.stream()
					.collect(Collectors.groupingBy(ContentAssocDO::getAssocId));
			for (Map<String, Object> datum : data) {
				Long id = Long.parseLong(datum.get("id").toString());
				if (collect.containsKey(id)){
					datum.put("isEmptyFile",false);
					datum.put("fileList",collect.get(id));
				}else {
					datum.put("isEmptyFile",true);
				}
			}

			int total = candidateInfoDao.pageCount(pageParam);
			result.put("data", new DsResultResponse(pageParam.getPageno(), pageParam.getPagesize(), total, data));

		}
		return result;
	}

}
